package com.syh.jn.scm.domain.supplier.entity.finance;

import cn.redscarf.commons.util.bean.ExtBeanUtils;
import cn.redscarf.commons.util.other.ExtAssert;
import cn.redscarf.commons.util.validator.ValidationUtils;
import com.syh.core.ddd.domain.AbstractSimpleAggregate;
import com.syh.core.ddd.domain.CodeExpEnum;
import com.syh.core.ddd.domain.CodeGenerateUtil;
import com.syh.jn.scm.dto.supplier.finance.IncomeBillMto;
import com.syh.jn.scm.dto.supplier.finance.IncomeBillSto;
import com.syh.jn.scm.dto.supplier.finance.IncomeBillVo;
import com.syh.jn.scm.dto.support.FilesDto;
import com.syh.jn.scm.exception.BusinessException;
import com.syh.jn.scm.service.api.supplier.finance.enums.IncomeBillEnum;
import lombok.Data;
import lombok.EqualsAndHashCode;

import java.math.BigDecimal;
import java.util.UUID;

/**
 * 收入单
 */
@Data
@EqualsAndHashCode(callSuper = true)
public class IncomeBill extends AbstractSimpleAggregate<Long> {
  public IncomeBill() {}

  public IncomeBill(IncomeBillVo vo) {
    ExtAssert.notNull(vo, "对象为空");
    if (vo.getId() == null)
      throw new BusinessException("缺少必要参数");
    ExtBeanUtils.copyProperties(vo, this);
  }

  /**
   * 创建收入单
   * @param sto
   * @return
   */
  public static IncomeBill createIncomeBill(IncomeBillSto sto){
    ExtAssert.notNull(sto, "对象为空");
    ValidationUtils.validate(sto);
    IncomeBill bill = IncomeBill.systemCreate(sto);

    bill.setUuid(UUID.randomUUID().toString());
    bill.setCode(CodeGenerateUtil.codeGenerate(CodeExpEnum.INCOME_BILL_EXP.getCodeExp(),sto.getCustomerId()));
    return bill;
  }

  /**
   * 修改费用单
   * @param mto
   */
  public void modify(IncomeBillMto mto){
    ExtAssert.notNull(mto, "对象为空");
    ValidationUtils.validate(mto);
    if (!this.state.equals(IncomeBillEnum.STAYCONFIRM.getStatus())) {
      throw new BusinessException("收入单不是新建状态,修改失败!");
    }
    ExtBeanUtils.copyProperties(mto, this);
    this.lastUpdateTimeStamp = System.currentTimeMillis();
  }
  /**
   * 取消
   */
  public void cancel(){
    if (!this.state.equals(IncomeBillEnum.STAYCONFIRM.getStatus())) {
      throw new BusinessException("收入单不是待确认状态，无法取消！!");
    }
    if (!this.state.equals(IncomeBillEnum.OTHERPARTY_STAYCONFIRM.getStatus())) {
      throw new BusinessException("收入单对方已确认，无法取消！!");
    }
    this.state = IncomeBillEnum.CANCEL.getStatus();
  }
  /**
   * 确认
   */
  public void confirm(){
    if (!this.state.equals(IncomeBillEnum.STAYCONFIRM.getStatus())) {
      throw new BusinessException("收入单不是待确认状态，无法确认！!");
    }
    this.state = IncomeBillEnum.CONFIRM.getStatus();
    //TODO 如果是物流公司的费用单 直接确认有效
    if (this.customerType == 2) {
      this.confirmState = IncomeBillEnum.OTHERPARTY_CONFIRM.getStatus();
    }
  }
  /**
   * 取消确认
   */
  public void cancelConfirm(){
    if (!this.state.equals(IncomeBillEnum.CONFIRM.getStatus())) {
      throw new BusinessException("收入单不是已确认状态，无法取消确认！!");
    }
    this.state = IncomeBillEnum.STAYCONFIRM.getStatus();
    //TODO 如果是物流公司的费用单 直接取消有效
    if (this.customerType == 2) {
      this.confirmState = IncomeBillEnum.OTHERPARTY_STAYCONFIRM.getStatus();
    }
  }
  /**
   * 生成对账单
   */
  public void generating(Long statementOfAccountId){
    if (this.state.equals(IncomeBillEnum.STATEMENT.getStatus())) {
      throw new BusinessException("收入单已生成对账单!");
    }
    this.statementOfAccountId = statementOfAccountId;
    this.state = IncomeBillEnum.STATEMENT.getStatus();
  }
  /**
   * 取消生成对账单
   */
  public void cancelGenerating(){
    if (!this.state.equals(IncomeBillEnum.STATEMENT.getStatus())) {
      throw new BusinessException("收入单已取消对账单!");
    }
    this.statementOfAccountId = null;
    this.state = IncomeBillEnum.CONFIRM.getStatus();
  }

  /**
   * 数据销毁
   */
  public void destroy() {
    if (!this.state.equals(IncomeBillEnum.CANCEL.getStatus())) {
      throw new BusinessException("收入单当前状态不允许,删除失败!");
    }
  }
  /**
   * 系统默认生成字段
   * @return
   */
  private static IncomeBill systemCreate(IncomeBillSto sto) {
    IncomeBill bill = new IncomeBill();
    ExtBeanUtils.copyProperties(sto, bill);
    bill.createTimeStamp = System.currentTimeMillis();
    bill.state = IncomeBillEnum.STAYCONFIRM.getStatus();
    bill.confirmState = IncomeBillEnum.OTHERPARTY_STAYCONFIRM.getStatus();
    return bill;
  }

  /**
   * 上传图片
   *
   * @param dto
   */
  public void upload(FilesDto dto) {
    this.mainSrcImages = dto.getFiles();
  }
  /**
   * 收入单编号
   */
  private String code;
  /**
   * 客户类型: 0上游, 1下游, 2物流
   */
  private Short customerType;
  /**
   * 客户id
   */
  private Long customerId;
  /**
   * 收入单状态:0待确认, 1已确认, 2已生成账单, 3已取消
   */
  private Short state;
  /**
   * 对账单id
   */
  private Long statementOfAccountId;
  /**
   * 录单人id
   */
  private Long brokerageId;
  /**
   * 录单日期
   */
  private Long inputTimestamp;
  /**
   * 收入金额
   */
  private BigDecimal price;
  /**
   * 备注
   */
  private String remark;
  /**
   * 对方确认生效状态：0未生效, 1已生效
   */
  private Short confirmState;
  /**
   * 归属端id
   */
  private Long businessEntityId;
  /**
   * 单据图片
   */
  private String mainSrcImages;
}
